# -*- coding: utf-8 -*-

import socket
import thread
import time
import sys
import os
import httplib, urllib
import re

def Server_Alive_Init():
    conn = httplib.HTTPConnection("10.24.12.4")
    output = os.popen("hostname")
    hostname = GetHostname()
    sn = GetSerialNumber()
    #print hostname + " || " + sn
    params = urllib.urlencode({'task':'Handshake', 'sn':sn, 'hostname':hostname})
    headers = {"Content-type": "application/x-www-form-urlencoded"}
    conn.request("POST", "/kanbix/api.service.php", params, headers)
    response = conn.getresponse() 
    if response.status == 200:
        data = response.read()  
        print "Response: "+data
    conn.close()
    Server_Alive_Loop(conn,data)

def Server_Alive_Loop (conn,uuid):
    params = "{\"uuid\":\""+uuid+"\",\"info\":\""+"Product Name:"+GetProductName()+","+GetSystemVersion()+","+GetCpuInfo()+","+GetMemFree()+","+GetMemTotal()+","+GetSwapFree()+","+GetSwapTotal()+","+GetLoadAverage()+","+GetDiskUsageOfRoot()+","+GetDiskInfo()+","+GetPortService()+"\"}"
    headers = {"Content-type": "application/json"}
    conn.request("POST", "/kanbix/api.service.php?task=TellAlive&contentType=JSON", params, headers)
    response = conn.getresponse()
    if response.status == 200:
        data = response.read()
        print "Alive: "+data
    conn.close()
    time.sleep(300)
    Server_Alive_Loop (conn,uuid)

def GetUptime():
    output = os.popen("uptime | awk '{print $3}'")
    uptime = output.read()
    uptime = uptime.replace("\n","")
    return "Uptime:"+uptime
def GetSystemVersion():
    output = os.popen("cat /proc/version")
    sysver = output.read()
    sysver = sysver.replace("\n","")
    sysver = sysver.replace(",","")
    return "System Version:"+sysver;
def GetHostname():
    output = os.popen("hostname")
    hostname = output.read()
    hostname = hostname.replace("\n","")
    return hostname
def GetLoadAverage():
    output = os.popen("""awk '{print $1"/1min "$2"/5min "$3"/15min"}' /proc/loadavg""")
    loadavg =  output.read();
    loadavg = loadavg.replace("\n","")
    return "Load Average:"+loadavg;
def GetMemTotal():
    output = os.popen("cat /proc/meminfo |grep 'MemTotal'")
    memtotal = output.read()
    memtotal = memtotal.replace("\n","")
    memtotal = memtotal.replace(" ","")
    return memtotal
def GetMemFree():
    output = os.popen("cat /proc/meminfo |grep 'MemFree'")
    memfree = output.read()
    memfree = memfree.replace("\n","")
    memfree = memfree.replace(" ","")
    return memfree
def GetSwapTotal():
    output = os.popen("cat /proc/meminfo |grep 'SwapTotal'")
    swaptotal = output.read()
    swaptotal = swaptotal.replace("\n","")
    swaptotal = swaptotal.replace(" ","")
    return swaptotal
def GetSwapFree():
    output = os.popen("cat /proc/meminfo |grep 'SwapFree'")
    swapfree = output.read()
    swapfree = swapfree.replace("\n","")
    swapfree = swapfree.replace(" ","")
    return swapfree
def GetDiskUsageOfRoot():
    output = os.popen("""df -h | grep '\/$' |awk '{print $3"/"$2, $5"used"}'""")
    du = output.read()
    du = du.replace("\n","")
    return "DiskUsageOf /:"+du   
def GetCpuInfo():
    output = os.popen("""cat /proc/cpuinfo |grep 'model name' | awk 'gsub(/model name\t: /,"") gsub(/[ ]+/," ")  {print $0}'""")
    cpuinfo = output.read()
    cpuinfo = cpuinfo.replace("\n","#|#")
    cpuinfo = "CPU Info:"+cpuinfo
    return cpuinfo

def GetSerialNumber():
    output = os.popen("dmidecode | grep 'Serial Number:'")
    n = re.split(r"[\s]*Serial Number: ",output.read())
    if n[1]:
        return n[1]
    else :
        return 
def GetProductName():
    output = os.popen("dmidecode | grep 'Product Name:'")
    n = re.split(r"[\s]*Product Name: ",output.read())
    if n[1]:
        return n[1]
    else :
        return
def GetPortService():
    output = os.popen("""netstat -anp |grep LISTEN |grep tcp|awk '{print "IP/Port:"$4" PID/Service:"$7}'""")
    ports = output.read()
    ports = ports.replace("\n","#|#")
    ports = ports.replace(",",".")
    return "Network Services:"+ports
def GetDiskInfo():
    output = os.popen("fdisk -l | grep 'Disk /'")
    disk = output.read()
    disk = disk.replace("\n","#|#")
    disk = disk.replace(",","")
    return "Disk Info:"+disk

def TCP_Server (host,port):
    try:
        Server_Alive_Init();
        tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        tcp_server.bind((host,port))
        tcp_server.listen(16)
    except socket.error, msg:
        print 'Socket error'
        tcp_server.close()
        exit()
    except KeyboardInterrupt:
        print 'Keyboard Interrupted'
        tcp_server.close()
        exit()
    global client_max, client_lock
    print 'Server is ready, binding port', port
    while 1:
        try:
            if (1<client_max):
                c, addr = tcp_server.accept()
                print 'Get connection from ', addr
                thread.start_new_thread(ServerThread,(c, addr))
            else:
                c, addr = tcp_server.accept()
                print 'Server is too busy'
                c.send('Refused')
                c.close()
        except socket.error, msg:
            print 'Socker error'
            tcp_server.close()
            exit()
        except KeyboardInterrupt:
            print 'Keyboard Interrupted'
            tcp_server.close()
            exit()

def ServerThread (c, addr):
    global client_max, client_lock, client_current
    login = UserLogin(c, addr)
    try:
        if (login):
            pass
        else:
            c.send('Invalid login')
            print 'Refused a connection'
            print 'Connection remains: ', client_max
            c.close()
            exit()
    except socket.error, msg:
        print 'Socket error (ThreadErr.#1)'
        c.close()
        exit()
    c.send('Accepted')
    client_lock.acquire()
    client_max -= 1;
    client_lock.release()
    print 'Accepted a connection'
    print 'Connection remains: ', client_max
    while 1:
        try:
            k = c.recv(1024)
            print "Recieved from client ", addr, ": ",k
	    if(k.lower()=="exit"):
                break
            output = os.popen(k)
            o = output.read()
            c.send(str(len(o)))
            c.send(o)
        except socket.error, msg:
            break
        except KeyboardInterrupt:
            break
    c.close()
    client_lock.acquire()
    client_max += 1;
    client_lock.release()
    print 'A client', addr, 'disconnected'
    print 'Connection remains: ', client_max

def UserLogin (c, addr):
    try:
        c.send('Anonymous is not allowed, please login')
       	usr = c.recv(1024)
       	c.send('Username Okay, please input password')
        pwd = c.recv(1024)
        if(usr==pwd):
            return 1
        else:
            return 0
    except socket.error, msg:
        return 0

if __name__ == '__main__':
    try:
        print u'-'
	print u'LastUpdate: 20120620 R1'
        print u'MgrServ Ver 0.1.0'
        command = sys.argv[1:]
        host = ''
        port = ''
        if len(command)>0 and command[0].isdigit():
            port = int(command[0])
        while port > 65535 or port < 1024:
            port = raw_input("Please define port to bind (1024-65535) > ")
            if (port == ''):
                port = 0;
            port = (int)(port)
        client_max = 5
        client_lock = thread.allocate_lock()
        server = TCP_Server (host,port)
    except KeyboardInterrupt:
        print "\r\nKeyboardInterrupt"
        exit()

